import { Context, Next } from 'hono'
import { AuthService, JWTPayload } from '@/services/authService'
import { AuthenticationError, AuthorizationError } from '@/middleware/errorHandler'

const authService = new AuthService()

// 认证中间件
export const authMiddleware = () => {
  return async (c: Context, next: Next) => {
    try {
      // 从Authorization头获取token
      const authHeader = c.req.header('authorization')
      if (!authHeader || !authHeader.startsWith('Bearer ')) {
        throw new AuthenticationError('Missing or invalid authorization header')
      }

      const token = authHeader.substring(7) // 移除 "Bearer " 前缀
      
      // 验证token
      const payload = authService.verifyToken(token)
      
      // 将用户信息添加到上下文
      c.set('user', payload)
      c.set('userId', payload.sub)
      
      await next()
    } catch (error) {
      if (error instanceof AuthenticationError) {
        throw error
      }
      throw new AuthenticationError('Invalid authentication token')
    }
  }
}

// 可选认证中间件（token可选）
export const optionalAuthMiddleware = () => {
  return async (c: Context, next: Next) => {
    try {
      const authHeader = c.req.header('authorization')
      if (authHeader && authHeader.startsWith('Bearer ')) {
        const token = authHeader.substring(7)
        const payload = authService.verifyToken(token)
        c.set('user', payload)
        c.set('userId', payload.sub)
      }
    } catch (error) {
      // 可选认证失败时不抛出错误，继续执行
      console.warn('Optional auth failed:', error)
    }
    
    await next()
  }
}

// API密钥认证中间件
export const apiKeyMiddleware = () => {
  return async (c: Context, next: Next) => {
    try {
      // 从X-API-Key头获取API密钥
      const apiKey = c.req.header('x-api-key')
      if (!apiKey) {
        throw new AuthenticationError('Missing API key')
      }

      // 验证API密钥格式
      if (!apiKey.startsWith('bh_')) {
        throw new AuthenticationError('Invalid API key format')
      }

      // 导入ApiKeyService
      const { ApiKeyService } = await import('@/services/apiKeyService')
      const apiKeyService = new ApiKeyService()

      // 验证API密钥
      const result = await apiKeyService.findDeveloperByApiKey(apiKey)
      if (!result) {
        throw new AuthenticationError('Invalid or expired API key')
      }

      const { developer, apiKeyRecord } = result

      // 更新API密钥使用记录
      const clientIp = c.req.header('x-forwarded-for') || c.req.header('x-real-ip') || 'unknown'
      await apiKeyService.updateApiKeyUsage(apiKeyRecord.id, clientIp)

      // 将用户信息和API密钥信息添加到上下文
      c.set('user', {
        sub: developer.id,
        email: developer.email,
        username: developer.username,
        role: developer.role,
        iss: 'api-key',
        aud: 'api'
      })
      c.set('userId', developer.id)
      c.set('apiKey', apiKeyRecord)

      await next()
    } catch (error) {
      if (error instanceof AuthenticationError) {
        throw error
      }
      throw new AuthenticationError('Invalid API key')
    }
  }
}

// 认证检查中间件
export const requireAuth = async (c: Context, next: Next) => {
  const user = c.get('user') as JWTPayload | undefined

  if (!user) {
    throw new AuthenticationError('Authentication required')
  }

  await next()
}

// 角色检查中间件
export const requireRole = (requiredRoles: ('developer' | 'admin')[]) => {
  return async (c: Context, next: Next) => {
    const user = c.get('user') as JWTPayload | undefined

    if (!user) {
      throw new AuthenticationError('Authentication required')
    }

    if (!requiredRoles.includes(user.role as any)) {
      throw new AuthorizationError('Insufficient permissions')
    }

    await next()
  }
}

// 混合认证中间件（支持JWT或API密钥）
export const hybridAuthMiddleware = () => {
  return async (c: Context, next: Next) => {
    try {
      // 检查是否有API密钥
      const apiKey = c.req.header('x-api-key')
      if (apiKey) {
        // 验证API密钥格式
        if (!apiKey.startsWith('bh_')) {
          throw new AuthenticationError('Invalid API key format')
        }

        // 导入ApiKeyService
        const { ApiKeyService } = await import('@/services/apiKeyService')
        const apiKeyService = new ApiKeyService()

        // 验证API密钥
        const result = await apiKeyService.findDeveloperByApiKey(apiKey)
        if (!result) {
          throw new AuthenticationError('Invalid or expired API key')
        }

        const { developer, apiKeyRecord } = result

        // 更新API密钥使用记录
        const clientIp = c.req.header('x-forwarded-for') || c.req.header('x-real-ip') || 'unknown'
        await apiKeyService.updateApiKeyUsage(apiKeyRecord.id, clientIp)

        // 将用户信息和API密钥信息添加到上下文
        c.set('user', {
          sub: developer.id,
          email: developer.email,
          username: developer.username,
          role: developer.role,
          iss: 'api-key',
          aud: 'api'
        })
        c.set('userId', developer.id)
        c.set('apiKey', apiKeyRecord)

        await next()
        return
      }

      // 检查是否有JWT token
      const authHeader = c.req.header('authorization')
      if (authHeader && authHeader.startsWith('Bearer ')) {
        const token = authHeader.substring(7) // 移除 "Bearer " 前缀

        // 验证token
        const payload = authService.verifyToken(token)

        // 将用户信息添加到上下文
        c.set('user', payload)
        c.set('userId', payload.sub)

        await next()
        return
      }

      // 没有提供任何认证信息
      throw new AuthenticationError('Authentication required. Provide either Bearer token or X-API-Key header.')
    } catch (error) {
      if (error instanceof AuthenticationError) {
        throw error
      }
      throw new AuthenticationError('Authentication failed')
    }
  }
}

// 获取当前用户信息
export const getCurrentUser = (c: Context): JWTPayload | undefined => {
  return c.get('user') as JWTPayload | undefined
}

// 获取当前API密钥信息
export const getCurrentApiKey = (c: Context): any | undefined => {
  return c.get('apiKey')
}

// 管理员权限验证中间件
export const adminMiddleware = () => {
  return async (c: Context, next: Next) => {
    try {
      const user = getCurrentUser(c)
      if (!user) {
        throw new AuthenticationError('Authentication required')
      }

      // 检查用户角色
      if (user.role !== 'admin') {
        throw new AuthorizationError('Admin permission required')
      }

      // 验证用户状态（从数据库获取最新状态）
      const { prisma } = await import('@/lib/database')
      const dbUser = await prisma.developer.findUnique({
        where: { id: user.sub },
        select: { role: true, status: true }
      })

      if (!dbUser) {
        throw new AuthenticationError('User not found')
      }

      if (dbUser.role !== 'admin') {
        throw new AuthorizationError('Admin permission required')
      }

      if (dbUser.status !== 'active') {
        throw new AuthorizationError('Admin account is not active')
      }

      await next()
    } catch (error) {
      throw error
    }
  }
}

// 获取当前用户ID
export const getCurrentUserId = (c: Context): string | undefined => {
  return c.get('userId') as string | undefined
}

// 检查是否已认证
export const isAuthenticated = (c: Context): boolean => {
  return !!c.get('user')
}
